/*
 *
 *  * Copyright (c) 2016. For Intelligent Group
 *
 */

package com.intelligent.ispc.r.analysis.spc;

import com.google.common.collect.Maps;
import com.intelligent.ispc.common.utils.StringUtils;
import com.intelligent.ispc.core.dto.CPWarningRuleDto;
import com.intelligent.ispc.utils.RuleLevelType;

import java.util.List;
import java.util.Map;

/**
 * Created by Can.Guan on 2016/9/8.
 */
public class ScatterConfiguration {
    private Map<String, CPWarningRuleDto> cpWarnMap = null;
    private int digitNum = 6;

    /**
     * set warning rules
     *
     * @param cpWarnList warning rules list
     */
    public void setCPWarningRules(List<CPWarningRuleDto> cpWarnList) {
        if (cpWarnList != null) {
            cpWarnMap = Maps.newHashMap();
            for (CPWarningRuleDto obj : cpWarnList) {
                cpWarnMap.put(StringUtils.upperCase(obj.getIndiceName()), obj);
            }
        }
    }

    /**
     * set warning rules
     *
     * @param iType  type of value to check
     * @param iValue value to check
     * @return check result
     */
    public String getLevelType(CpType iType, double iValue) {
        RuleLevelType gtype = RuleLevelType.NORMAL;
        if (cpWarnMap != null) {
            String sName = iType.getName();
            if (cpWarnMap.containsKey(sName)) {
                CPWarningRuleDto tempObj = cpWarnMap.get(sName);
                if (tempObj != null) {
                    if (iType == CpType.CA) {
                        //ca may be negatives
                        iValue = Math.abs(iValue);
                        if (tempObj.getExcellentBoundaryValue() != null && iValue <= Double.valueOf(tempObj.getExcellentBoundaryValue())) {
                            gtype = RuleLevelType.EXCELLENT;
                        } else if (tempObj.getGoodBoundaryValue() != null && iValue <= Double.valueOf(tempObj.getGoodBoundaryValue())) {
                            gtype = RuleLevelType.GOOD;
                        } else if (tempObj.getAcceptableBoundaryValue() != null && iValue <= Double.valueOf(tempObj.getAcceptableBoundaryValue())) {
                            gtype = RuleLevelType.ACCEPTABLE;
                        } else if (tempObj.getRectificationBoundaryValue() != null && iValue <= Double.valueOf(tempObj.getRectificationBoundaryValue())) {
                            gtype = RuleLevelType.ABOVE_RECTIFICATION;
                        } else if (tempObj.getRectificationBoundaryValue() != null && iValue > Double.valueOf(tempObj.getRectificationBoundaryValue())) {
                            gtype = RuleLevelType.RECTIFICATION;
                        }
                    } else {
                        if (tempObj.getExcellentBoundaryValue() != null && iValue >= Double.valueOf(tempObj.getExcellentBoundaryValue())) {
                            gtype = RuleLevelType.EXCELLENT;
                        } else if (tempObj.getGoodBoundaryValue() != null && iValue >= Double.valueOf(tempObj.getGoodBoundaryValue())) {
                            gtype = RuleLevelType.GOOD;
                        } else if (tempObj.getAcceptableBoundaryValue() != null && iValue >= Double.valueOf(tempObj.getAcceptableBoundaryValue())) {
                            gtype = RuleLevelType.ACCEPTABLE;
                        } else if (tempObj.getRectificationBoundaryValue() != null && iValue >= Double.valueOf(tempObj.getRectificationBoundaryValue())) {
                            gtype = RuleLevelType.ABOVE_RECTIFICATION;
                        } else if (tempObj.getRectificationBoundaryValue() != null && iValue < Double.valueOf(tempObj.getRectificationBoundaryValue())) {
                            gtype = RuleLevelType.RECTIFICATION;
                        }
                    }
                }
            }
        }
        return gtype.toString();
    }

    /**
     * check value with CPK type
     *
     * @param iValue value to check
     */
    public String getLevelTypeByCPK(double iValue) {
        return getLevelType(CpType.CPK, iValue);
    }

    /**
     * check value with CP type
     * @param iValue value to check
     */
    public String getLevelTypeByCP(double iValue) {
        return getLevelType(CpType.CP, iValue);
    }

    /**
     * check value with CPL type
     * @param iValue value to check
     */
    public String getLevelTypeByCPL(double iValue) {
        return getLevelType(CpType.CPL, iValue);
    }

    /**
     * check value with CPU type
     * @param iValue value to check
     */
    public String getLevelTypeByCPU(double iValue) {
        return getLevelType(CpType.CPU, iValue);
    }

    /**
     * check value with CA type
     * @param iValue value to check
     */
    public String getLevelTypeByCA(double iValue) {
        return getLevelType(CpType.CA, iValue);
    }

    /**
     * type of warning rules
     */
    enum CpType {
        CPK("CPK"),
        CP("CP"),
        CPL("CPL"),
        CPU("CPU"),
        CA("CA");

        private String name;

        CpType(String name) {
            this.name = name;
        }

        public String getName() {
            return this.name;
        }
    }

    public int getDigitNum() {
        return digitNum;
    }

    public void setDigitNum(int digitNum) {
        this.digitNum = digitNum;
    }
}
